import {Color} from '../color';
import {Plugin} from '../extend';
import {clamp, round} from '../helper';
import {AnyColor, LabaColor} from '../type';
import {getDeltaE00} from '../get/get-perceive-difference';
import {parseLaba, rgbaToLaba, roundLaba} from '../color/model/lab';

declare module '../color' {
    interface Color {
        /**
         * Converts a color to CIELAB color space and returns an object.
         * The object always includes `alpha` value [0, 1].
         */
        toLab(): LabaColor;

        /**
         * Calculates the perceived color difference for two colors according to
         * [Delta E2000](https://en.wikipedia.org/wiki/Color_difference#CIEDE2000).
         * Returns a value in [0, 1] range.
         */
        delta(color?: AnyColor | Color): number;
    }
}

/**
 * A plugin adding support for CIELAB color space.
 * https://en.wikipedia.org/wiki/CIELAB_color_space
 */
const labPlugin: Plugin = (ColorClass: typeof Color, parsers): void => {
    ColorClass.prototype.toLab = function() {
        return roundLaba(rgbaToLaba(this.rgba));
    };

    ColorClass.prototype.delta = function(color: any = '#FFF') {
        const compared = color instanceof ColorClass ? color : new ColorClass(color);
        const delta = getDeltaE00(this.toLab(), compared.toLab()) / 100;
        return clamp(round(delta, 3));
    };

    parsers.object.push([parseLaba, 'lab']);
};

export default labPlugin;
